home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
BasicMenuUI.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
30KB
|
713 lines
/*
* @(#)BasicMenuUI.java 1.94 98/06/22
*
* Copyright 1997, 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
package com.sun.java.swing.plaf.basic;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import com.sun.java.swing.*;
import com.sun.java.swing.event.*;
import com.sun.java.swing.plaf.*;
import com.sun.java.swing.border.*;
import java.io.Serializable;
/**
* A Windows L&F implementation of MenuUI. This implementation
* is a "combined" view/controller.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version 1.94 06/22/98
* @author Georges Saab
* @author David Karlton
* @author Arnaud Weber
*/
public class BasicMenuUI extends MenuUI implements Serializable
{
protected JMenu menu;
protected MouseListener mouseListener;
protected MouseMotionListener dragListener;
protected ChangeListener menuChangeListener;
protected PropertyChangeListener propertyChangeListener;
protected static Color pressedBackground;
protected static Color pressedForeground;
private int lastMnemonic = 0;
// visual constants
protected static final int defaultTextIconGap = 4;
protected Icon menuArrow = null;
protected Icon checkIcon = null;
protected boolean oldBorderPainted;
public static ComponentUI createUI(JComponent x) {
return new BasicMenuUI();
}
public void installUI(JComponent c) {
menu = (JMenu) c;
// Create and install listeners
menu.setDelay(200);
initListeners(c);
addListeners(c);
// Set defaults
c.setOpaque(true);
LookAndFeel.installBorder(c,"Menu.border");
oldBorderPainted = menu.isBorderPainted();
menu.setBorderPainted( ( (Boolean) (UIManager.get("MenuItem.borderPainted")) ).booleanValue() );
LookAndFeel.installColorsAndFont(c,
"Menu.background",
"Menu.foreground",
"Menu.font");
validateKeyboardAccelerator();
// Menu specific defaults
if (pressedBackground == null ||
pressedBackground instanceof UIResource) {
pressedBackground =
UIManager.getColor("Menu.pressedBackground");
}
if (pressedForeground == null ||
pressedForeground instanceof UIResource) {
pressedForeground =
UIManager.getColor("Menu.pressedForeground");
}
}
public void uninstallUI(JComponent c) {
menu.setArmed(false);
menu.setSelected(false);
removeListeners(c);
c.resetKeyboardActions();
LookAndFeel.uninstallBorder(c);
((JMenu) c).setBorderPainted( oldBorderPainted );
if (menuArrow instanceof UIResource)
menuArrow = null;
if (checkIcon instanceof UIResource)
checkIcon = null;
}
protected void validateKeyboardAccelerator() {
if(menu.getModel().getMnemonic() != lastMnemonic) {
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(lastMnemonic,ActionEvent.ALT_MASK,false));
lastMnemonic = menu.getModel().getMnemonic();
menu.registerKeyboardAction(new PostAction(menu,true),
KeyStroke.getKeyStroke(lastMnemonic,ActionEvent.ALT_MASK,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
}
protected MouseListener createMouseListener(JComponent c) {
return new MouseListener((JMenu)c);
}
protected MouseMotionListener createMouseMotionListener(JComponent c) {
return new BasicMenuMouseMotionListener();
}
protected ChangeListener createMenuChangeListener(JComponent c) {
return new MenuChangeListener((JMenu)c, this);
}
protected PropertyChangeListener createPropertyChangeListener(JComponent c) {
return new MenuPropertyChangeListener();
}
protected void initListeners(JComponent c) {
mouseListener = createMouseListener(c);
dragListener = createMouseMotionListener(c);
menuChangeListener = createMenuChangeListener(c);
propertyChangeListener = createPropertyChangeListener(c);
}
protected void addListeners(JComponent c) {
c.addMouseListener(mouseListener);
c.addMouseMotionListener(dragListener);
((JMenu)c).addChangeListener(menuChangeListener);
((JMenu)c).addPropertyChangeListener(propertyChangeListener);
}
protected void removeListeners(JComponent c) {
c.removeMouseListener(mouseListener);
c.removeMouseMotionListener(dragListener);
((JMenu)c).removeChangeListener(menuChangeListener);
((JMenu)c).removePropertyChangeListener(propertyChangeListener);
}
protected void installDefaultIcons() {
// Icons
if ((menu != null) &&
(menu.getParent() != null) &&
!(menu.getParent() instanceof JMenuBar)) {
if (menuArrow == null ||
menuArrow instanceof UIResource) {
menuArrow = UIManager.getIcon("Menu.arrowIcon");
}
if (checkIcon == null ||
checkIcon instanceof UIResource) {
checkIcon = UIManager.getIcon("MenuItem.checkIcon");
}
}
}
/**
* We draw the background in BasicGraphicsUtils.paintMenuItem()
* so override update (which fills the background of opaque
* components by default) to just call paint().
*
* @see BasicGraphicsUtils#paintMenuItem
*/
public void update(Graphics g, JComponent c) {
paint(g, c);
}
public void paint(Graphics g, JComponent c) {
installDefaultIcons();
ButtonModel bm = ((AbstractButton)c).getModel();
BasicGraphicsUtils.paintMenuItem(g, c, checkIcon, menuArrow,
pressedBackground, pressedForeground,
defaultTextIconGap);
}
public Dimension getMinimumSize(JComponent c) {
return getPreferredSize(c);
}
public Dimension getMaximumSize(JComponent c) {
return getPreferredSize(c);
}
public Insets getDefaultMargin(AbstractButton c) {
return new Insets(2,2,2,2);
}
public Dimension getPreferredSize(JComponent c) {
installDefaultIcons();
return BasicGraphicsUtils.getPreferredMenuItemSize(c,
checkIcon,
menuArrow,
defaultTextIconGap);
}
public void processMouseEvent(JMenuItem item,MouseEvent e,MenuElement path[],MenuSelectionManager manager) {
Point p = e.getPoint();
if (item.isEnabled() == false)
return;
if(p.x >= 0 && p.x < item.getWidth() &&
p.y >= 0 && p.y < item.getHeight()) {
JMenu menu = (JMenu)item;
MenuElement selectedPath[] = manager.getSelectedPath();
if(!(selectedPath.length > 0 &&
selectedPath[selectedPath.length-1] ==
menu.getPopupMenu())) {
if(menu.isTopLevelMenu() ||
menu.getDelay() == 0 ||
e.getID() == MouseEvent.MOUSE_DRAGGED) {
MenuElement newPath[] = new MenuElement[path.length+1];
System.arraycopy(path,0,newPath,0,path.length);
newPath[path.length] = menu.getPopupMenu();
manager.setSelectedPath(newPath);
} else {
manager.setSelectedPath(path);
setupPostTimer(menu);
}
}
} else if(e.getID() == MouseEvent.MOUSE_RELEASED) {
Component c = manager.componentForPoint(e.getComponent(), e.getPoint());
if (c == null)
manager.clearSelectedPath();
}
}
private int lower(int ascii) {
if(ascii >= 'A' && ascii <= 'Z')
return ascii + 'a' - 'A';
else
return ascii;
}
public void processKeyEvent(JMenuItem item,KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
int key = item.getMnemonic();
if(key == 0)
return;
if(e.getID() == KeyEvent.KEY_PRESSED) {
if(lower(key) == lower((int)(e.getKeyChar()))) {
JPopupMenu popupMenu = ((JMenu)item).getPopupMenu();
MenuElement sub[] = popupMenu.getSubElements();
if(sub.length > 0) {
MenuElement newPath[] = new MenuElement[path.length + 2];
System.arraycopy(path,0,newPath,0,path.length);
newPath[path.length] = popupMenu;
newPath[path.length+1] = sub[0];
manager.setSelectedPath(newPath);
}
e.consume();
}
}
}
protected void setupPostTimer(JMenu menu) {
Timer timer = new Timer(menu.getDelay(),new PostAction(menu,false));
timer.setRepeats(false);
timer.start();
}
static class PostAction extends AbstractAction {
JMenu menu;
boolean force=false;
PostAction(JMenu menu,boolean shouldForce) {
super("postAction");
this.menu = menu;
this.force = shouldForce;
}
public void actionPerformed(ActionEvent e) {
MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
if(force) {
Container cnt = menu.getParent();
if(cnt != null && cnt instanceof JMenuBar) {
MenuElement me[];
MenuElement subElements[];
subElements = menu.getPopupMenu().getSubElements();
if(subElements.length > 0) {
me = new MenuElement[4];
me[0] = (MenuElement) cnt;
me[1] = (MenuElement) menu;
me[2] = (MenuElement) menu.getPopupMenu();
me[3] = subElements[0];
defaultManager.setSelectedPath(me);
} else {
me = new MenuElement[2];
me[0] = (MenuElement)cnt;
me[1] = menu;
defaultManager.setSelectedPath(me);
}
}
} else {
MenuElement path[] = defaultManager.getSelectedPath();
if(path.length > 0 && path[path.length-1] == menu) {
MenuElement newPath[] = new MenuElement[path.length+1];
System.arraycopy(path,0,newPath,0,path.length);
newPath[path.length] = menu.getPopupMenu();
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
}
}
}
public boolean isEnabled() {
return menu.getModel().isEnabled();
}
}
class MenuPropertyChangeListener implements PropertyChangeListener, Serializable {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if(prop.equals(AbstractButton.MNEMONIC_CHANGED_PROPERTY)) {
validateKeyboardAccelerator();
}
}
}
static class MouseListener extends MouseAdapter implements Serializable {
JMenu menu;
public MouseListener(JMenu m) {
menu = m;
}
public void mousePressed(MouseEvent e) {
if(menu.isTopLevelMenu() && menu.isEnabled()) {
Point p = e.getPoint();
if(p.x >= 0 && p.x < menu.getWidth() &&
p.y >= 0 && p.y < menu.getHeight()) {
if(menu.isSelected()) {
MenuSelectionManager.defaultManager().clearSelectedPath();
} else {
Container cnt = menu.getParent();
if(cnt != null && cnt instanceof JMenuBar) {
MenuElement me[] = new MenuElement[2];
me[0]=(MenuElement)cnt;
me[1]=menu;
MenuSelectionManager.defaultManager().setSelectedPath(me);
}
}
}
}
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
public void mouseReleased(MouseEvent e) {
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
public void mouseEntered(MouseEvent e) {
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
public void mouseExited(MouseEvent e) {
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
}
public void menuCanceled(JMenu m) {
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
if(manager.isComponentPartOfCurrentMenu(m))
MenuSelectionManager.defaultManager().clearSelectedPath();
}
static class MenuChangeListener implements ChangeListener, Serializable {
JMenu menu;
BasicMenuUI ui;
boolean isSelected = false;
Component wasFocused;
public MenuChangeListener(JMenu m, BasicMenuUI ui) {
menu = m;
this.ui = ui;
validateKeyboardActions(menu.isSelected());
}
public void stateChanged(ChangeEvent e) {
validateKeyboardActions(menu.isSelected());
}
Component findFocusedComponent(Component c) {
Container parent;
for(parent = c.getParent() ; parent != null ; parent = parent.getParent()) {
if(parent instanceof java.awt.Window)
return ((java.awt.Window)parent).getFocusOwner();
}
return null;
}
void validateKeyboardActions(boolean sel) {
if(sel != isSelected) {
isSelected = sel;
if(isSelected) {
boolean isRequestFocusEnabled = menu.isRequestFocusEnabled();
wasFocused = findFocusedComponent(menu);
if(!isRequestFocusEnabled)
menu.setRequestFocusEnabled(true);
menu.requestFocus();
if(!isRequestFocusEnabled)
menu.setRequestFocusEnabled(false);
menu.registerKeyboardAction(new CancelAction(),
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
menu.registerKeyboardAction(new SelectNextItemAction(),
KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
menu.registerKeyboardAction(new SelectPreviousItemAction(),
KeyStroke.getKeyStroke(KeyEvent.VK_UP,0,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
menu.registerKeyboardAction(new SelectParentItemAction(),
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
menu.registerKeyboardAction(new SelectChildItemAction(),
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
menu.registerKeyboardAction(new ReturnAction(),
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,false),
JComponent.WHEN_IN_FOCUSED_WINDOW);
} else {
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0,false));
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0,false));
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0,false));
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0,false));
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0,false));
menu.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,false));
if(wasFocused != null) {
if(wasFocused instanceof JComponent) {
JComponent jc = (JComponent) wasFocused;
boolean isRFEnabled = jc.isRequestFocusEnabled();
if(!isRFEnabled)
jc.setRequestFocusEnabled(true);
wasFocused.requestFocus();
if(!isRFEnabled)
jc.setRequestFocusEnabled(false);
} else
wasFocused.requestFocus();
wasFocused = null;
}
}
}
}
private class CancelAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
MenuElement path[] = MenuSelectionManager.defaultManager().getSelectedPath();
if(path.length > 4) { /* PENDING(arnaud) Change this to 2 when a mouse grabber is available for MenuBar */
MenuElement newPath[] = new MenuElement[path.length - 2];
System.arraycopy(path,0,newPath,0,path.length-2);
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
} else
MenuSelectionManager.defaultManager().clearSelectedPath();
}
}
private class ReturnAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
MenuElement path[] = MenuSelectionManager.defaultManager().getSelectedPath();
MenuElement lastElement;
if(path.length > 0) {
lastElement = path[path.length-1];
if(lastElement instanceof JMenu) {
MenuElement newPath[] = new MenuElement[path.length+1];
System.arraycopy(path,0,newPath,0,path.length);
newPath[path.length] = ((JMenu)lastElement).getPopupMenu();
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
} else if(lastElement instanceof JMenuItem) {
MenuSelectionManager.defaultManager().clearSelectedPath();
((JMenuItem)lastElement).doClick(0);
((JMenuItem)lastElement).setArmed(false);
}
}
}
}
private MenuElement nextEnabledChild(MenuElement e[],int fromIndex) {
int i,c;
for(i=fromIndex,c=e.length ; i < c ; i++) {
if (e[i]!=null) {
Component comp = e[i].getComponent();
if(comp != null && comp.isEnabled())
return e[i];
}
}
return null;
}
private MenuElement previousEnabledChild(MenuElement e[],int fromIndex) {
int i;
for(i=fromIndex ; i >= 0 ; i--) {
if (e[i]!=null) {
Component comp = e[i].getComponent();
if(comp != null && comp.isEnabled())
return e[i];
}
}
return null;
}
private class SelectNextItemAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
MenuElement currentSelection[] = MenuSelectionManager.defaultManager().getSelectedPath();
if(currentSelection.length > 1) {
MenuElement parent = currentSelection[currentSelection.length-2];
if(parent.getComponent() instanceof JMenu) {
MenuElement childs[];
parent = currentSelection[currentSelection.length-1];
childs = parent.getSubElements();
if(childs.length > 0) {
MenuElement newPath[] = new MenuElement[currentSelection.length+1];
System.arraycopy(currentSelection,0,
newPath,0,currentSelection.length);
newPath[currentSelection.length] = nextEnabledChild(childs,0);
if(newPath[currentSelection.length] != null)
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
}
} else {
MenuElement childs[] = parent.getSubElements();
MenuElement nextChild;
int i,c;
for(i=0,c=childs.length;i<c;i++) {
if(childs[i] == currentSelection[currentSelection.length-1]) {
nextChild = nextEnabledChild(childs,i+1);
if(nextChild == null)
nextChild = nextEnabledChild(childs,0);
if(nextChild != null) {
currentSelection[currentSelection.length-1] = nextChild;
MenuSelectionManager.defaultManager().setSelectedPath(currentSelection);
}
break;
}
}
}
}
}
}
private class SelectPreviousItemAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
MenuElement currentSelection[] = MenuSelectionManager.defaultManager().getSelectedPath();
if(currentSelection.length > 1) {
MenuElement parent = currentSelection[currentSelection.length-2];
if(parent.getComponent() instanceof JMenu) {
MenuElement childs[];
parent = currentSelection[currentSelection.length-1];
childs = parent.getSubElements();
if(childs.length > 0) {
MenuElement newPath[] = new MenuElement[currentSelection.length+1];
System.arraycopy(currentSelection,0,
newPath,0,currentSelection.length);
newPath[currentSelection.length] = previousEnabledChild(childs,childs.length-1);
if(newPath[currentSelection.length] != null)
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
}
} else {
MenuElement childs[] = parent.getSubElements();
MenuElement nextChild;
int i,c;
for(i=0,c=childs.length;i<c;i++) {
if(childs[i] == currentSelection[currentSelection.length-1]) {
nextChild = previousEnabledChild(childs,i-1);
if(nextChild == null)
nextChild = previousEnabledChild(childs,childs.length-1);
if(nextChild != null) {
currentSelection[currentSelection.length-1] = nextChild;
MenuSelectionManager.defaultManager().setSelectedPath(currentSelection);
}
break;
}
}
}
}
}
}
private class SelectParentItemAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
MenuElement path[] = MenuSelectionManager.defaultManager().getSelectedPath();
if(path.length > 3 && path[path.length-3].getComponent() instanceof JMenu &&
!((JMenu)path[path.length-3].getComponent()).isTopLevelMenu()) {
MenuElement newPath[] = new MenuElement[path.length-2];
System.arraycopy(path,0,newPath,0,path.length-2);
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
} else if(path.length > 0 && path[0].getComponent() instanceof JMenuBar) {
MenuElement nextMenu=null,popup=null,firstItem=null;
MenuElement tmp[];
int i,c;
if(path.length > 1) {
MenuElement previousElement;
tmp = path[0].getSubElements();
for(i=0,c=tmp.length;i<c;i++) {
if(tmp[i] == path[1]) {
nextMenu = previousEnabledChild(tmp,i-1);
if(nextMenu == null)
nextMenu = previousEnabledChild(tmp,tmp.length-1);
}
}
}
if(nextMenu != null) {
MenuElement newSelection[];
popup = ((JMenu)nextMenu).getPopupMenu();
if(((JMenu)nextMenu).isTopLevelMenu())
firstItem = null;
else {
tmp = popup.getSubElements();
if(tmp.length > 0)
firstItem = nextEnabledChild(tmp,0);
}
if(firstItem != null) {
newSelection = new MenuElement[4];
newSelection[0] = path[0];
newSelection[1] = nextMenu;
newSelection[2] = popup;
newSelection[3] = firstItem;
} else {
newSelection = new MenuElement[3];
newSelection[0] = path[0];
newSelection[1] = nextMenu;
newSelection[2] = popup;
}
MenuSelectionManager.defaultManager().setSelectedPath(newSelection);
}
}
}
}
private class SelectChildItemAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
MenuElement path[] = MenuSelectionManager.defaultManager().getSelectedPath();
if(path.length > 0 && path[path.length-1].getComponent().isEnabled() &&
path[path.length-1].getComponent() instanceof JMenu &&
!((JMenu)path[path.length-1].getComponent()).isTopLevelMenu()) {
MenuElement newPath[] = new MenuElement[path.length+2];
MenuElement subElements[];
System.arraycopy(path,0,newPath,0,path.length);
newPath[path.length] = ((JMenu)path[path.length-1].getComponent()).getPopupMenu();
subElements = newPath[path.length].getSubElements();
if(subElements.length > 0) {
newPath[path.length+1] = nextEnabledChild(subElements,0);
MenuSelectionManager.defaultManager().setSelectedPath(newPath);
}
} else if(path.length > 0 && path[0].getComponent() instanceof JMenuBar) {
MenuElement nextMenu=null,popup=null,firstItem=null;
MenuElement tmp[];
int i,c;
if(path.length > 1) {
tmp = path[0].getSubElements();
for(i=0,c=tmp.length;i<c;i++) {
if(tmp[i] == path[1]) {
nextMenu = nextEnabledChild(tmp,i+1);
if(nextMenu == null)
nextMenu = nextEnabledChild(tmp,0);
}
}
}
if(nextMenu != null) {
MenuElement newSelection[];
popup = ((JMenu)nextMenu).getPopupMenu();
if(((JMenu)nextMenu).isTopLevelMenu())
firstItem = null;
else {
tmp = popup.getSubElements();
if(tmp.length > 0)
firstItem = nextEnabledChild(tmp,0);
}
if(firstItem != null) {
newSelection = new MenuElement[4];
newSelection[0] = path[0];
newSelection[1] = nextMenu;
newSelection[2] = popup;
newSelection[3] = firstItem;
} else {
newSelection = new MenuElement[3];
newSelection[0] = path[0];
newSelection[1] = nextMenu;
newSelection[2] = popup;
}
MenuSelectionManager.defaultManager().setSelectedPath(newSelection);
}
}
}
}
}
}